package main

import (
	"fmt"
	"io"
	"my-zinx/znet"
	"net"
	"os"
	"strconv"
	"time"
)

type Resp struct {
	MsgID   uint64 `json:"msg_id"`
	DataLen uint64 `json:"data_len"`
	Data    string `json:"data"`
}

func (r *Resp) String() string {
	return fmt.Sprintf("MsgID: %d, DataLen: %d\nData: %s", r.MsgID, r.DataLen, r.Data)
}

func MainClient() {
	msgID := 300
	if len(os.Args) > 1 {
		id, _ := strconv.ParseInt(os.Args[1], 10, 64)
		msgID = int(id)
	}

	fmt.Println("Client... start")

	// 3秒之后发起连接请求，给服务端开启服务的机会
	time.Sleep(3 * time.Second)

	conn, err := net.Dial("tcp", "127.0.0.1:7777")
	if err != nil {
		fmt.Println("client start err: ", err)
		return
	}

	for {
		dp := znet.NewDataPack()
		sendData, err := dp.Pack(znet.NewMessage(uint64(msgID), []byte("Hello Server")))
		if err != nil {
			fmt.Println("pack err: ", err)
			return
		}

		if _, err := conn.Write(sendData); err != nil {
			fmt.Println("write error err: ", err)
			return
		}

		recvHead := make([]byte, dp.GetHeadLen())
		if _, err := io.ReadFull(conn, recvHead); err != nil {
			fmt.Println("io read head err: ", err)
			return
		}

		recvMsg, err := dp.Unpack(recvHead)
		if err != nil {
			fmt.Println("unpack err: ", err)
			return
		}

		if recvMsg.GetDataLen() > 0 {
			msg := recvMsg.(*znet.Message)
			msg.Data = make([]byte, msg.DataLen)

			if _, err := io.ReadFull(conn, msg.Data); err != nil {
				fmt.Println("io read data err: ", err)
				return
			}

			resp := &Resp{
				MsgID:   msg.ID,
				DataLen: msg.DataLen,
				Data:    string(msg.Data),
			}

			fmt.Printf(" server call back:\n%+v", resp)

		}

		time.Sleep(1 * time.Second)
	}
}

func main() {
	MainClient()
	//sendDataPack()
}

func sendDataPack() {
	conn, err := net.Dial("tcp", "127.0.0.1:7777")
	if err != nil {
		fmt.Println("net dial err: ", err)
		return
	}

	dp := znet.NewDataPack()

	msg1 := znet.NewMessage(0, []byte("hello"))
	msg2 := znet.NewMessage(1, []byte("world!!!"))

	data1, err := dp.Pack(msg1)
	if err != nil {
		fmt.Println("pack msg1 err: ", err)
		return
	}
	data2, err := dp.Pack(msg2)
	if err != nil {
		fmt.Println("pack msg2 err: ", err)
		return
	}

	// 手动组成粘包
	data := append(data1, data2...)

	if _, err := conn.Write(data); err != nil {
		fmt.Println("write err: ", err)
		return
	}

	//select {} // 客户端阻塞
}
